#pragma once
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include "Log.hpp"
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <functional>

#include <sys/wait.h>

namespace kzz
{
    class InetAddr
    {

    public:
        InetAddr(){}
    
        // 主机转网络
        InetAddr(const std::string &ip, const uint16_t &port) : _ip(ip), _port(port)
        {
            _addr.sin_family = AF_INET;
            //_addr.sin_addr.s_addr = inet_addr(_ip.c_str());
            inet_pton(AF_INET, _ip.c_str(), &_addr.sin_addr.s_addr);
            _addr.sin_port = htons(_port);
        }
        // 专门用于服务器，接受所有IP，只传端口号
        InetAddr(const uint16_t &port) : _port(port)
        {
            _addr.sin_family = AF_INET;
            _addr.sin_addr.s_addr = INADDR_ANY;
            _addr.sin_port = htons(_port);
           // _ip = inet_ntoa(_addr.sin_addr);
             char ipbuffer[64];
            inet_ntop(AF_INET, &_addr.sin_addr, ipbuffer, sizeof(_addr));
            _ip = ipbuffer;
        }
       
        //拷贝构造
         InetAddr(const InetAddr &peer)
         {
            _ip = peer._ip;
            _port = peer._port;
            _addr = peer._addr;
            _len = peer._len;
         }
         public:
         void SetAddr(const struct sockaddr_in &addr)
        {
         
            _addr=addr;
             char ipbuffer[64];
            inet_ntop(AF_INET, &_addr.sin_addr, ipbuffer, sizeof(_addr));
            _ip = ipbuffer;
            _port = ntohs(_addr.sin_port);

        }
         // 网络转主机
        InetAddr(const struct sockaddr_in &addr)
        {
            SetAddr(addr);
        }
        bool operator==(const InetAddr &peer) const
        {
            return _port == peer._port && _ip == peer._ip;
        }




        std::string InetName()
        {
            return _ip+std::to_string(_port);

        }
        InetAddr & operator=(const InetAddr &peer)
        {
            _ip = peer._ip;
            _port = peer._port;
            _addr = peer._addr;
            _len = peer._len;
            return *this;
        }

    public:
        const uint16_t &Port() const
        {
            return _port;
            // return ntohs(_addr.sin_port) ;
        }
        const std::string &Ip() const
        {
            return _ip;
            // return inet_ntoa(_addr.sin_addr) ;
        }
        struct sockaddr *Addr() const
        {
            return (sockaddr *)&_addr;
        }
        socklen_t &Len()
        {
            return _len;
        }

    private:
        uint16_t _port;
        std::string _ip;
        struct sockaddr_in _addr;
        socklen_t _len = sizeof(sockaddr_in);
    };
}